/*
 * Diego da Rocha Borges
 * Otávio Zabaleta
 */

#ifndef AST_H
#define	AST_H

#include <stdlib.h>
#include "symbol_table.h"
#include "tac.h"

#define AST_MAX_SYMBOLS 2
#define AST_MAX_SONS 4

#define AST_ADD                 1
#define AST_SUB                 2
#define AST_MUL                 3
#define AST_DIV                 4
#define AST_LEAF                5
#define AST_ASS                 6
#define AST_LCMD                7
#define AST_IF                  8
#define AST_IF_ELSE             9
#define AST_WHILE               10
#define AST_PRINT_STRING        11
#define AST_RETURN              12
#define AST_READ                13
#define AST_OPERATOR_OR         14
#define AST_OPERATOR_AND        15
#define AST_OPERATOR_L          16
#define AST_OPERATOR_LE         17
#define AST_OPERATOR_G          18
#define AST_OPERATOR_GE         19
#define AST_OPERATOR_EQ         20
#define AST_OPERATOR_NE         21
#define AST_OPERATOR_NOT        22
#define AST_ASS_VEC             24
#define AST_CMD_BLOCK           25
#define AST_FUNC_CALL           26
#define AST_PARAM_LIST          27
#define AST_PARAM               28
#define AST_VAR_DEF             29
#define AST_VEC_DEF             30
#define AST_FUNC_DEF            31
#define AST_BYTE_TYPE           32
#define AST_INT_TYPE            33
#define AST_FUNC_PARAM_LIST     34
#define AST_EXPR                35
#define AST_PRINT_EXPR          36
#define AST_DEFS                37
#define AST_EXPR_PAR            38
#define AST_IDENTIFIER          39
#define AST_LIT_INT             40
#define AST_LIT_CHAR            41
#define AST_VEC_REF      42

/**
 * Abstract Syntaxe Tree Node
 */
typedef struct ast {
    int type;
    HASH_NODE* symbol[AST_MAX_SYMBOLS];
    struct ast* sons[AST_MAX_SONS];
    int line_number;
    
}AST;

/**
 * Creates a Abstract Syntaxe Tree Node
 *
 * @param type node type (one of the defines above)
 * @param symbol0 hash pointer to any relevant data
 * @param symbol1 hash pointer to any relevant data
 * @param s0 AST pointer to first son
 * @param s1 AST pointer to second son
 * @param s2 AST pointer to third son
 * @param s3 AST pointer to fourth son
 *
 * @return new AST node
 */
AST* ast_create(int type, HASH_NODE* symbol0, HASH_NODE* symbol1, AST* s0, AST* s1, AST* s2, AST* s3, int line_number);

/**
 * Prints one node of the abstract syntaxe tree
 *
 * @param n the node to be printed
 */
    void ast_print_one(AST* n);

/**
 * Executes a function received as a parameter for each node of an abstract syntaxe tree
 * @param a Abstract syntaxe tree
 * @param fun function to be executed over the nodes of the abstract syntaxe tree
 */
void ast_for_each_do(AST* a, void (* fun)(AST* a));


TAC* ast_generate_tac_code(AST *root);
#endif	/* AST_H */

